package com.lu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lu.core.support.DataScopeProxy;
import com.lu.mapper.SysBrandMapper;
import com.lu.mapper.SysMerchantMapper;
import com.lu.mapper.SysStoreMapper;
import com.lu.mapper.SysUserMapper;
import com.lu.model.domain.BrandMerchantStoreImport;
import com.lu.model.entity.SysMerchant;
import com.lu.model.entity.SysStore;
import com.lu.model.entity.SysUser;
import com.lu.model.enums.ApprovalStatusEnum;
import com.lu.model.enums.SysUserTypeEnum;
import com.lu.model.exception.LuBootAssert;
import com.lu.model.request.StoreAddRequest;
import com.lu.model.request.StoreQueryRequest;
import com.lu.model.request.UserAddRequest;
import com.lu.service.SysBrandService;
import com.lu.service.SysMerchantService;
import com.lu.service.SysStoreService;
import com.lu.service.SysUserService;
import com.lu.support.datascope.SimpleDataScopePermission;
import com.lu.utils.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 门店 服务实现类
 * </p>
 *
 * @author currentCodeAuthor
 * @since 2022-07-31
 */
@RequiredArgsConstructor
@Service
public class SysStoreServiceImpl extends ServiceImpl<SysStoreMapper, SysStore> implements SysStoreService {

  private final SysUserService userService;
  private final SysUserMapper userMapper;
  private final SysBrandMapper brandMapper;
  private final SysMerchantMapper merchantMapper;

  private final SysBrandService brandService;
  private final SysMerchantService merchantService;

  private final DataSourceTransactionManager transactionManager;
  private final TransactionDefinition transactionDefinition;

  @Override
  public Page<SysStore> pageList(StoreQueryRequest request) {
    QueryWrapper<SysStore> storeQueryWrapper = new QueryWrapper<>();
    if (ObjectUtil.isNotEmpty(request.getBusinessMode())) {
      storeQueryWrapper.eq("business_mode", request.getBusinessMode());
    }
    if (ObjectUtil.isNotEmpty(request.getRelationId())) {
      storeQueryWrapper.eq("relation_id", request.getRelationId());
    }
    if (ObjectUtil.isNotEmpty(request.getStatus())) {
      storeQueryWrapper.eq("status", request.getStatus());
    }
    if (ObjectUtil.isNotEmpty(request.getProvince())) {
      storeQueryWrapper.eq("province", request.getProvince());
    }
    if (ObjectUtil.isNotEmpty(request.getCity())) {
      storeQueryWrapper.eq("city", request.getCity());
    }
    if (ObjectUtil.isNotEmpty(request.getRegion())) {
      storeQueryWrapper.eq("region", request.getRegion());
    }
    if (ObjectUtil.isNotEmpty(request.getLongitude())) {
      storeQueryWrapper.eq("longitude", request.getLongitude());
    }
    if (ObjectUtil.isNotEmpty(request.getLatitude())) {
      storeQueryWrapper.eq("latitude", request.getLatitude());
    }
    if (ObjectUtil.isNotEmpty(request.getName())) {
      storeQueryWrapper.like("name", request.getName());
    }
    if (ObjectUtil.isNotEmpty(request.getContactsName())) {
      storeQueryWrapper.like("contacts_name", request.getContactsName());
    }
    if (ObjectUtil.isNotEmpty(request.getContactsPhone())) {
      storeQueryWrapper.like("contacts_phone", request.getContactsPhone());
    }
    storeQueryWrapper.orderByDesc("sort", "create_time");
    Page<SysStore> storePage = this.baseMapper
        .selectPage(new Page<>(request.getPageIndex(), request.getPageSize()), storeQueryWrapper);
    if (ObjectUtil.isEmpty(storePage.getRecords())) {
      return storePage;
    }
    QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
    userQueryWrapper.select("id", "username");
    userQueryWrapper.in("id",
        storePage.getRecords().stream().map(SysStore::getUserId).collect(Collectors.toList()));
    Map<Long, List<SysUser>> userMap = userMapper.selectList(userQueryWrapper).stream()
        .collect(Collectors.groupingBy(SysUser::getId));
    for (SysStore store : storePage.getRecords()) {
      //品牌下的商户的线下门店
      List<SysUser> users = userMap.get(store.getUserId());
      if (ObjectUtil.isNotEmpty(users)) {
        store.setUsername(users.get(0).getUsername());
      }
    }
    return storePage;
  }

  @Override
  public List<SysStore> storeList(StoreQueryRequest request) {
    QueryWrapper<SysStore> storeQueryWrapper = new QueryWrapper<>();
    if (ObjectUtil.isNotEmpty(request.getBusinessMode())) {
      storeQueryWrapper.eq("business_mode", request.getBusinessMode());
    }
    if (ObjectUtil.isNotEmpty(request.getRelationId())) {
      storeQueryWrapper.eq("relation_id", request.getRelationId());
    }
    if (ObjectUtil.isNotEmpty(request.getStatus())) {
      storeQueryWrapper.eq("status", request.getStatus());
    }
    if (ObjectUtil.isNotEmpty(request.getProvince())) {
      storeQueryWrapper.eq("province", request.getProvince());
    }
    if (ObjectUtil.isNotEmpty(request.getCity())) {
      storeQueryWrapper.eq("city", request.getCity());
    }
    if (ObjectUtil.isNotEmpty(request.getRegion())) {
      storeQueryWrapper.eq("region", request.getRegion());
    }
    if (ObjectUtil.isNotEmpty(request.getLongitude())) {
      storeQueryWrapper.eq("longitude", request.getLongitude());
    }
    if (ObjectUtil.isNotEmpty(request.getLatitude())) {
      storeQueryWrapper.eq("latitude", request.getLatitude());
    }
    if (ObjectUtil.isNotEmpty(request.getName())) {
      storeQueryWrapper.like("name", request.getName());
    }
    if (ObjectUtil.isNotEmpty(request.getContactsName())) {
      storeQueryWrapper.like("contacts_name", request.getContactsName());
    }
    if (ObjectUtil.isNotEmpty(request.getContactsPhone())) {
      storeQueryWrapper.like("contacts_phone", request.getContactsPhone());
    }
    storeQueryWrapper.orderByDesc("sort", "create_time");
    DataScopeProxy.executeConfig(DataScopeProxy.DataScope.builder().name("relation_id").handler(SimpleDataScopePermission.class).build());
    List<SysStore> storeList = this.baseMapper.selectList(storeQueryWrapper);
    List<SysStore> storeList2 = this.baseMapper.list();
    List<SysStore> storeList3 = this.baseMapper.groupByList();
    return storeList;
  }

  @Transactional(rollbackFor = Exception.class)
  @Override
  public Long addStore(StoreAddRequest request) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(request.getStatus())
        && Arrays.stream(ApprovalStatusEnum.values())
        .anyMatch(o -> o.getStatus() == request.getStatus()), "无效的状态参数");
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(request.getBusinessMode())
        && Arrays.stream(SysMerchant.BusinessMode.values())
        .anyMatch(o -> o.getMode() == request.getBusinessMode()), "无效的经营模式参数");
//    this.checkPhoneUnique(null, request.getContactsPhone());
    this.checkNameUnique(null, request.getName());
    //新增用户，创建好账号
    UserAddRequest addRequest = new UserAddRequest();
    addRequest.setUsername(request.getUsername());
    addRequest.setPassword(request.getPassword());
    addRequest.setRealName(request.getContactsName());
    addRequest.setCompany(request.getName());
    Long userId = userService.addUser(addRequest);
    //新增门店
    SysStore store = new SysStore();
    BeanUtil.copyProperties(request, store);
    store.setUserId(userId);
    store.setCreateUserId(SecurityUtil.getCurrentUser().getId());
    store.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    this.baseMapper.insert(store);
    return store.getId();
  }

  @Override
  public SysStore updateStore(SysStore store) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(store.getId()), "修改失败");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(store.getStatus())
        || Arrays.stream(ApprovalStatusEnum.values())
        .anyMatch(o -> o.getStatus() == store.getStatus()), "无效的状态参数");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(store.getBusinessMode())
        || Arrays.stream(SysMerchant.BusinessMode.values())
        .anyMatch(o -> o.getMode() == store.getBusinessMode()), "无效的经营模式参数");
    this.checkNameUnique(store.getId(), store.getName());
    store.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    store.setUpdateTime(LocalDateTime.now());
    this.baseMapper.updateById(store);
    return this.baseMapper.selectById(store.getId());
  }

  @Override
  public String delete(Long id) {
    SysStore store = this.baseMapper.selectById(id);
    //删除用户
    String rs = userService.deleteUser(store.getUserId());
    //删除商户
    int res = this.baseMapper.deleteById(id);
    return res + "==" + rs;
  }

  @Override
  public List<String> importStore(String originalFilename, InputStream inputStream) {
    //检查品牌是否存在，若不存在则添加品牌
    ExcelReader reader = ExcelUtil.getReader(inputStream);
    reader.addHeaderAlias("区域", "region");
    reader.addHeaderAlias("蛋糕品牌", "brandName");
    reader.addHeaderAlias("门店", "storeName");
    reader.addHeaderAlias("联系方式", "contact");
    reader.addHeaderAlias("地址", "address");
    reader.addHeaderAlias("线下门店/电子券", "businessMode");
    reader.addHeaderAlias("营业开始时间", "businessHoursStart");
    reader.addHeaderAlias("营业结束时间", "businessHoursEnd");
    List<BrandMerchantStoreImport> brandMerchantStores = reader
        .read(2, 3, BrandMerchantStoreImport.class);
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(brandMerchantStores), "excel数据格式不正确");
    brandMerchantStores.stream().forEach(o -> {
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getBrandName()), "品牌名称不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getStoreName()), "门店名称不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getContact()), "联系方式不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getAddress()), "详细地址不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getBusinessHoursStart()), "营业开始时间不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getBusinessHoursEnd()), "营业结束时间不能为空");
      LuBootAssert.isTrue(ObjectUtil.isNotEmpty(o.getBusinessMode()) &&
          (SysStore.BusinessMode.OFFLINE.getDescription().equals(o.getBusinessMode())
              || SysStore.BusinessMode.ELECTRONIC_COUPON.getDescription()
              .equals(o.getBusinessMode())), "经营模式不能为空，且值为 线下或电子券");
      o.setBusinessHoursStart(DateUtil
          .format(DateUtil.parse(o.getBusinessHoursStart(), DatePattern.NORM_DATETIME_PATTERN),
              DatePattern.NORM_TIME_PATTERN));
      o.setBusinessHoursEnd(DateUtil
          .format(DateUtil.parse(o.getBusinessHoursEnd(), DatePattern.NORM_DATETIME_PATTERN),
              DatePattern.NORM_TIME_PATTERN));
      o.setBrandName(o.getBrandName().trim());
      o.setStoreName(o.getStoreName().trim());
    });
    List<String> msgs = new ArrayList<>();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
    Map<String, String> provinceMap = new HashMap<>();
    Map<String, String> provinceCityMap = new HashMap<>();
    return msgs;
  }

  @Override
  public List<SysStore> loginUserOfflineStores() {
    //登录账号若是门店若是商户
    SysMerchant merchant = SecurityUtil.getCurrentUser().getMerchant();
    LuBootAssert.isTrue(
        SecurityUtil.getCurrentUser().getUserType() == SysUserTypeEnum.SYS_MERCHANT_USER.getType()
            && merchant != null, "当前登录账号不是商户账号");
    QueryWrapper<SysStore> sysStoreQueryWrapper = new QueryWrapper<>();
    sysStoreQueryWrapper.eq("relation_id", merchant.getId());
    sysStoreQueryWrapper.eq("business_mode", SysStore.BusinessMode.OFFLINE.getMode());
    return this.baseMapper.selectList(sysStoreQueryWrapper);
  }

  private void checkPhoneUnique(Long id, String phone) {
    if (ObjectUtil.isEmpty(phone)) {
      return;
    }
    QueryWrapper<SysStore> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("contacts_phone", phone);
    if (ObjectUtil.isNotEmpty(id)) {
      queryWrapper.ne("id", id);
    }
    Integer count = this.baseMapper.selectCount(queryWrapper);
    LuBootAssert.isTrue(count == 0, "联系人手机号不能重复");
  }

  private void checkNameUnique(Long id, String name) {
    if (ObjectUtil.isEmpty(name)) {
      return;
    }
    QueryWrapper<SysStore> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", name);
    if (ObjectUtil.isNotEmpty(id)) {
      queryWrapper.ne("id", id);
    }
    Integer count = this.baseMapper.selectCount(queryWrapper);
    LuBootAssert.isTrue(count == 0, "名称不能重复");
  }


}
